package com.delta.rafg.core.database.impl.util;

import java.util.ArrayList;
import java.util.List;

import net.sf.jsqlparser.expression.AllComparisonExpression;
import net.sf.jsqlparser.expression.AnyComparisonExpression;
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.DateValue;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.InverseExpression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.TimeValue;
import net.sf.jsqlparser.expression.TimestampValue;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.drop.Drop;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.FromItemVisitor;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.OrderByVisitor;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SubJoin;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.Union;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;

public class JSqlVisitor implements SelectVisitor, FromItemVisitor,
		StatementVisitor, OrderByVisitor  {

	private List<String> tables = new ArrayList<String>();
	private List<String> columns = new ArrayList<String>();
	private List<String> fromItems = new ArrayList<String>();
	private List<String> orderBy = new ArrayList<String>();
	
	private boolean isSelect = false;
	private boolean isAllColumns = false;
	
	public List<String> getTables() {
		return tables;
	}

	public List<String> getColumns() {
		return columns;
	}

	public List<String> getFromItems() {
		return fromItems;
	}

	public List<String> getOrderBy() {
		return orderBy;
	}

	public boolean isSelect() {
		return isSelect;
	}
	
	public boolean isAllColumns() {
		return isAllColumns;
	}

	@Override
	public void visit(Table arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Table)");
		tables.add(arg0.getWholeTableName());
	}

	@Override
	public void visit(SubSelect arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(SubSelect)");

	}

	@Override
	public void visit(SubJoin arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(SubJoin)");

	}

	@Override
	public void visit(PlainSelect arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(PlainSelect)");
		if (arg0.getSelectItems() != null) {
			for (Object o : arg0.getSelectItems()) {
				if (o instanceof SelectExpressionItem) {
					SelectExpressionItem s = (SelectExpressionItem) o;
					columns.add(s.toString());	
				} else if (o instanceof AllColumns) {
					isAllColumns = true;
				}
			}
		}
		if (arg0.getOrderByElements() != null) {
			for (Object o : arg0.getOrderByElements()) {
				if (o instanceof OrderByElement) {
					OrderByElement s = (OrderByElement) o; 
					orderBy.add((String) s.toString());
				}
			}
		}
		arg0.getFromItem().accept(this);
	}

	@Override
	public void visit(Union arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Union)");

	}

	@Override
	public void visit(Select arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Select)");
		isSelect = true;
		arg0.getSelectBody().accept(this);
	}

	@Override
	public void visit(Delete arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Delete)");
		
	}

	@Override
	public void visit(Update arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Update)");
		
	}

	@Override
	public void visit(Insert arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Insert)");
		
	}

	@Override
	public void visit(Replace arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Replace)");
		
	}

	@Override
	public void visit(Drop arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Drop)");
		
	}

	@Override
	public void visit(Truncate arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(Truncate)");
		
	}

	@Override
	public void visit(CreateTable arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(CreateTable)");
		
	}

	@Override
	public void visit(OrderByElement arg0) {
//		AxisLogger.debug("JSqlVisitor() visit(OrderByElement)");
		Expression expr = arg0.getExpression();
		OrderByVisitor orderByVisitor = new OrderByVisitor();
		expr.accept(orderByVisitor);
		orderBy.addAll(orderByVisitor.getColumns());
	}

	private class OrderByVisitor implements ExpressionVisitor {
		private List<String> cols = new ArrayList<String>(); 

		public List<String> getColumns() {
			return cols;
		}

		@Override
		public void visit(NullValue arg0) {
		}

		@Override
		public void visit(Function arg0) {
		}

		@Override
		public void visit(InverseExpression arg0) {
		}

		@Override
		public void visit(JdbcParameter arg0) {
		}

		@Override
		public void visit(DoubleValue arg0) {
		}

		@Override
		public void visit(LongValue arg0) {
		}

		@Override
		public void visit(DateValue arg0) {
		}

		@Override
		public void visit(TimeValue arg0) {
		}

		@Override
		public void visit(TimestampValue arg0) {
		}

		@Override
		public void visit(Parenthesis arg0) {
		}

		@Override
		public void visit(StringValue arg0) {
		}

		@Override
		public void visit(Addition arg0) {
		}

		@Override
		public void visit(Division arg0) {
		}

		@Override
		public void visit(Multiplication arg0) {
		}

		@Override
		public void visit(Subtraction arg0) {
		}

		@Override
		public void visit(AndExpression arg0) {
		}

		@Override
		public void visit(OrExpression arg0) {
		}

		@Override
		public void visit(Between arg0) {
		}

		@Override
		public void visit(EqualsTo arg0) {
		}

		@Override
		public void visit(GreaterThan arg0) {
		}

		@Override
		public void visit(GreaterThanEquals arg0) {
		}

		@Override
		public void visit(InExpression arg0) {
		}

		@Override
		public void visit(IsNullExpression arg0) {
		}

		@Override
		public void visit(LikeExpression arg0) {
		}

		@Override
		public void visit(MinorThan arg0) {
		}

		@Override
		public void visit(MinorThanEquals arg0) {
		}

		@Override
		public void visit(NotEqualsTo arg0) {
		}

		@Override
		public void visit(Column arg0) {
			cols.add(arg0.getColumnName());
		}

		@Override
		public void visit(SubSelect arg0) {
		}

		@Override
		public void visit(CaseExpression arg0) {
		}

		@Override
		public void visit(WhenClause arg0) {
		}

		@Override
		public void visit(ExistsExpression arg0) {
		}

		@Override
		public void visit(AllComparisonExpression arg0) {
		}

		@Override
		public void visit(AnyComparisonExpression arg0) {
		}

		@Override
		public void visit(Concat arg0) {
		}

		@Override
		public void visit(Matches arg0) {
		}

		@Override
		public void visit(BitwiseAnd arg0) {
		}

		@Override
		public void visit(BitwiseOr arg0) {
		}

		@Override
		public void visit(BitwiseXor arg0) {
		}
		
	}
}

